package com.example.magnet.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.URLUtil;
import com.example.magnet.annotations.IgnoreAuth;
import com.example.magnet.consts.RedisKeyConst;
import com.example.magnet.dto.CurrentPlayer;
import com.example.magnet.dto.request.UpdateUserInfo;
import com.example.magnet.entity.WxUser;
import com.example.magnet.enums.Game2048LevelEnum;
import com.example.magnet.oss.FileService;
import com.example.magnet.service.WxUserService;
import com.example.magnet.util.AuthUtil;
import com.example.magnet.util.RedisUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/wx")
public class WxController {
    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private FileService fileService;



    // 微信小程序登录接口
    @GetMapping("/wxLogin/{code}")
    @IgnoreAuth
    public String login(@PathVariable String code) throws WxErrorException {


        WxMaJscode2SessionResult sessionInfo =
                wxMaService.getUserService().getSessionInfo(code);

        // 已经有token了，还用之前的token
        if (redisUtil.hasKey(RedisKeyConst.AUTH + sessionInfo.getOpenid())) {
            return redisUtil.getObj(RedisKeyConst.AUTH + sessionInfo.getOpenid(), String.class);
        }

        WxUser wxUser = wxUserService.getByWxId(sessionInfo.getOpenid());
        // 没有用户自己创建用户
        if (wxUser == null) {
            wxUser = new WxUser();
            wxUser.setWxId(sessionInfo.getOpenid());
            wxUser.setCreateTime(LocalDateTime.now());
            wxUser.setGame2048MaxScore(0);
            wxUser.setGameXiaoxiaoMaxScore(0);
            wxUser.setGame2048Level(Game2048LevelEnum.LV1);
            wxUser.setStar(0);

            wxUserService.save(wxUser);
        }
        String token = UUID.randomUUID().toString();
        CurrentPlayer currentPlayer = new CurrentPlayer();
        BeanUtils.copyProperties(wxUser, currentPlayer);
        currentPlayer.setSession(sessionInfo);
        redisUtil.setObject(RedisKeyConst.AUTH + token, currentPlayer);
        redisUtil.setObject(RedisKeyConst.AUTH + currentPlayer.getWxId(), token);
        return token;
    }

    @GetMapping("/me")
    public CurrentPlayer getCurrentUser() {
        return AuthUtil.getCurrPlayer();
    }

    @PostMapping("/updateUser")
    public void updateUser(@RequestBody UpdateUserInfo updateUserInfo) throws MalformedURLException {

        WxUser wxUser = wxUserService.getById(AuthUtil.getCurrPlayerId());
        wxUser.setWxUsername(updateUserInfo.getNickName());

        // 头像
        String headUrl = updateUserInfo.getHeadUrl();
        InputStream stream = URLUtil.getStream(new URL(headUrl));
        String url = fileService.uploadOss("userHeader" + wxUser.getWxId() + ".png", stream);
        wxUser.setWxHead(url);
        CurrentPlayer currPlayer = AuthUtil.getCurrPlayer();
        currPlayer.setWxHead(url);
        currPlayer.setWxUsername(updateUserInfo.getNickName());

        redisUtil.setObject(RedisKeyConst.AUTH + AuthUtil.getToken(), currPlayer);


        wxUserService.updateById(wxUser);
    }

    @PostMapping("/setTyro")
    public void setTyro() {

        wxUserService
                .lambdaUpdate()
                .set(WxUser::getTyro, 0)
                .eq(WxUser::getId, AuthUtil.getCurrPlayerId())
                .update();
        CurrentPlayer currPlayer = AuthUtil.getCurrPlayer();
        currPlayer.setTyro(0);
        redisUtil.setObject(RedisKeyConst.AUTH + AuthUtil.getToken(), currPlayer);
    }

    @GetMapping("/tokenEffective")
    @IgnoreAuth
    public boolean tokenEffective(@RequestParam String token) {
        return redisUtil.hasKey(RedisKeyConst.AUTH + token);
    }


    @GetMapping("/getTop10")
    public List<WxUser> getTop10() {
        return wxUserService.lambdaQuery()
                .orderByDesc(WxUser::getGame2048MaxScore)
                .last("limit 10")
                .list();
    }
}
